﻿//----------------------------------------------------------------
// Copyright (C) 2015-2020 PeachSystem Co.,Ltd.
// All rights reserved.
//
// 文件:WXHelper.cs
// 摘要:微信工具类
// 说明:
//

//当前版本：1.0.0
//作    者：陶剑扬
//完成日期：2014-11-07
//----------------------------------------------------------------
using System;
using System.Web;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;

using PeachSystem.XBase.Web;
using PeachSystem.XBase.WX.Helpers;
using PeachSystem.XBase.WX.Entites;
using PeachSystem.XBase.WX.Entites.Message;
using PeachSystem.XBase.WX.Entites.Original;

namespace PeachSystem.XBase.WX
{
    public class WXHelper
    {
        #region 常量

        const string ENCODING_UTF8 = "utf-8";
        const string URL_API_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";

        #endregion

        #region 属性

        /// <summary>
        /// Config
        /// </summary>
        public WXConfig Config { get; set; }


        #endregion

        #region 构造

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="config">配置</param>
        public WXHelper(WXConfig config)
        {
            Config = config;
        }

        #endregion

        #region 获取AccessToken

        /// <summary>
        /// 获取AccessToken
        /// </summary>
        /// <returns>AccessToken</returns>
        public AccessToken GetAccessToken()
        {
            try
            {
                OAccessToken o = JSONHelper.GetEntity<OAccessToken>(WebHelper.GetHTML(string.Format(URL_API_TOKEN, Config.AppID, Config.AppSecret), ENCODING_UTF8));
                AccessToken token = new AccessToken();
                token.Token = o.access_token;
                token.ExpiresIn = o.expires_in;
                return token;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion

        #region 检查签名

        /// <summary>
        /// 检查签名
        /// 加密/校验流程如下：
        /// 1. 将token、timestamp、nonce三个参数进行字典序排序
        /// 2. 将三个参数字符串拼接成一个字符串进行sha1加密
        /// 3. 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
        /// </summary>
        /// <param name="signature"></param>
        /// <param name="timestamp"></param>
        /// <param name="nonce"></param>
        /// <returns></returns>
        public bool CheckSignature(string signature, string timestamp, string nonce)
        {
            List<string> list = new List<string>();
            list.Add(Config.Token);
            list.Add(timestamp);
            list.Add(nonce);

            //排序
            list.Sort();

            //拼串
            string input = string.Empty;
            foreach (var item in list)
            {
                input += item;
            }

            //验证
            return signature == Cryptography.SHA1(input);
        }

        /// <summary>
        /// 检查签名
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public bool CheckSignature(HttpContext cx)
        {
            string signature = cx.Request["signature"];
            string timestamp = cx.Request["timestamp"];
            string nonce = cx.Request["nonce"];

            List<string> list = new List<string>();
            list.Add(Config.Token);
            list.Add(timestamp);
            list.Add(nonce);
            //排序
            list.Sort();
            //拼串
            string input = string.Empty;
            foreach (var item in list)
            {
                input += item;
            }
            //加密
            string new_signature = Cryptography.SHA1(input);
            //验证
            if (new_signature == signature)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        #endregion

        /// <summary>
        /// 获取信息
        /// </summary>
        /// <param name="msg_signature">msg_signature</param>
        /// <param name="timestamp">timestamp</param>
        /// <param name="nonce">nonce</param>
        /// <param name="encrypt_msg">encrypt_msg</param>
        /// <returns>xml string</returns>
        public string GetMessage(string msg_signature, string timestamp, string nonce, string encrypt_msg)
        {
            string message = "";
            int result = 0;

            WXBizMsgCrypt wx = new WXBizMsgCrypt(Config.Token, Config.EncodingAESKey, Config.AppID);
            result = wx.DecryptMsg(msg_signature, timestamp, nonce, encrypt_msg, ref message);

            return message;
            //if (result == 0)
            //{
            //    return new RMessageBase();
            //}
            //else
            //{
            //    return null;
            //}
        }
    }
}
